package com.alks.function.controller.task;


import com.alks.common.aop.RedisLock;
import com.alks.common.data.dto.SysUserTokenDTO;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.beanutils.ObjectUtils;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.finance.costcheck.PcCostLotDto;
import com.alks.function.data.dto.finance.costcheck.PcLotHeadDto;
import com.alks.function.data.dto.finance.fincons.SettlementSummaryDto;
import com.alks.function.data.dto.finance.fincons.SettlementSummaryDto2;
import com.alks.function.data.request.finance.costcheck.LotCostRequest;
import com.alks.function.mapper.finance.costcheck.PcLotCostMapper;
import com.alks.function.mapper.finance.fincons.SettlementPayableMapper;
import com.alks.function.service.impl.asyncImpl.LotCostAsyncServiceImpl;
import com.alks.function.service.impl.finance.costcheck.PcLotCostServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 财务部
 * 指令成本定时计算
 */
@Component
@Slf4j
@EnableScheduling
@EnableAsync
public class FinanceLotCostTask {

    @Autowired
    private PcLotCostMapper pcLotCostMappe;

    @Autowired
    private LotCostAsyncServiceImpl lotCostAsyncService;

    @Autowired
    private PcLotCostServiceImpl pcLotCostService;

    /**
     * 每天早上0点查询产出欠数为0的指令新增数据
     */
    @Async("TaskExecutor")
    @Scheduled(cron = "0 0 0 * * ?") // 每天0点执行
    //@Scheduled(initialDelay = 5000, fixedRate = 86400000) // 5秒后首次执行，之后每天执行一
    @Transactional
    @RedisLock(key = "task:FinanceLotCostTask.ScheduleInsertPcLotCostTask")
    public void ScheduleInsertPcLotCostTask(){
        try{
            log.info("定时任务执行开始, 指令成本定时新增数据中：");
            //1.待完工指令查询
            List<PcLotHeadDto> list = pcLotCostMappe.getNotCompleteLotDetail(null,new LotCostRequest());
            if(ObjectUtils.isEmpty(list)){
                throw new ServiceErrorException("没有数据！");
            }
            //2.LastQs为0或者空的才新增计算成本
            List<PcLotHeadDto> costList = list.stream()
                    .filter(item -> item.getLastQs() == 0)
                    .collect(Collectors.toList());
            if(ObjectUtils.isEmpty(costList)){
                throw new ServiceErrorException("没有产出欠数为0的需要计算指令成本！");
            }

            //3.构建要自动计算的指令数据
            List<PcCostLotDto> pcCostLotDtoList = new ArrayList<>();
            for (PcLotHeadDto dto : costList) {
                PcCostLotDto pcCostLotDto = new PcCostLotDto();
                BeanUtils.copyProperties(dto,pcCostLotDto);
                pcCostLotDto.setCompanyId(dto.getCompanyId());
                pcCostLotDto.setOutQtyQs(dto.getOrderQty());
                pcCostLotDto.setJQDate(dto.getDeliveryDate());
                pcCostLotDto.setOutQtyQs(dto.getOutQtyQs());
                pcCostLotDto.setOutDate(dto.getOutDate());
                pcCostLotDto.setSysDate(new Date());
                pcCostLotDto.setRemark("自动");
                pcCostLotDto.setSysUser("系统账户");
                pcCostLotDtoList.add(pcCostLotDto);
            }

            //4.系统自动 》》新增指令成本
            int count = pcLotCostMappe.addCostBatch(pcCostLotDtoList);
            log.info("定时任务执行成功, 指令成本定时新增数据结束！");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 每天早上0点30计算未封账的指令计算指令成本
     */
    @Async("TaskExecutor")
    @Scheduled(cron = "0 30 0 * * ?")
    //@Scheduled(initialDelay = 5000, fixedRate = 86400000) // 5秒后首次执行，之后每天执行一
    @RedisLock(key = "task:FinanceLotCostTask.ScheduleUpdateAmtOfPcLotCostTask")
    public void ScheduleUpdateAmtOfPcLotCostTask(){
        log.info("定时任务执行开始, 指令成本定时计算中：");
        lotCostAsyncService.InsertCalculation(null);
        log.info("定时任务执行成功, 指令成本定时计算！");
    }




}
